home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / mawk10.zip / CAST.C < prev    next >
C/C++ Source or Header  |  1991-10-05  |  9KB  |  394 lines

  1.  
  2. /********************************************
  3. cast.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the AWK programming language.
  8.  
  9. Mawk is distributed without warranty under the terms of
  10. the GNU General Public License, version 2, 1991.
  11. ********************************************/
  12.  
  13.  
  14. /*   $Log:    cast.c,v $
  15.  * Revision 3.4.1.1  91/09/14  17:22:49  brennan
  16.  * VERSION 1.0
  17.  * 
  18.  * Revision 3.4  91/08/16  10:32:08  brennan
  19.  * SW_FP_CHECK for V7 XNX23A
  20.  * 
  21.  * Revision 3.3  91/08/13  06:50:56  brennan
  22.  * VERSION .9994
  23.  * 
  24.  * Revision 3.2  91/06/28  04:16:12  brennan
  25.  * VERSION 0.999
  26.  * 
  27.  * Revision 3.1  91/06/07  10:27:00  brennan
  28.  * VERSION 0.995
  29.  * 
  30.  * Revision 2.5  91/06/04  06:42:57  brennan
  31.  * removed <string.h>
  32.  * 
  33.  * Revision 2.4  91/05/28  15:17:32  brennan
  34.  * removed STRING_BUFF back to temp_buff.string_buff
  35.  * 
  36.  * Revision 2.3  91/05/28  09:04:27  brennan
  37.  * removed main_buff
  38.  * 
  39.  * Revision 2.2  91/05/16  12:19:31  brennan
  40.  * cleanup of machine dependencies
  41.  * 
  42.  * Revision 2.1  91/04/08  08:22:44  brennan
  43.  * VERSION 0.97
  44.  * 
  45. */
  46.  
  47.  
  48. /*  cast.c  */
  49.  
  50. #include "mawk.h"
  51. #include "field.h"
  52. #include "memory.h"
  53. #include "scan.h"
  54. #include "repl.h"
  55.  
  56. int pow2[NUM_CELL_TYPES] = {1,2,4,8,16,32,64,128,256,512} ;
  57.  
  58. void cast1_to_d( cp )
  59.   register CELL *cp ;
  60. {
  61.   switch( cp->type )
  62.   { case C_NOINIT :  cp->dval = 0.0 ; break ;
  63.  
  64.     case C_DOUBLE :  return ;
  65.  
  66.     case C_MBSTRN :
  67.     case C_STRING :  
  68.           { register STRING *s = (STRING *) cp->ptr  ;
  69.  
  70. #if FPE_TRAPS_ON  /* look for overflow error */
  71.             errno = 0 ;
  72.             cp->dval = strtod(s->str,(char **)0) ;
  73.             if ( errno && cp->dval != 0.0 ) /* ignore underflow */
  74.                 rt_error("overflow converting %s to double", s) ;
  75. #else
  76.             cp->dval = strtod(s->str,(char **)0) ;
  77. #endif
  78.             free_STRING(s) ;
  79.           }
  80.             break ;
  81.  
  82.     case C_STRNUM :  
  83.       /* don't need to convert, but do need to free the STRING part */
  84.             free_STRING( string(cp) ) ;
  85.             break ;
  86.  
  87.  
  88.     default :
  89.             bozo("cast on bad type") ;
  90.   }
  91.   cp->type = C_DOUBLE ;
  92. }
  93.  
  94. void cast2_to_d( cp )
  95.   register CELL *cp ;
  96. { register STRING *s ;
  97.  
  98.   switch( cp->type )
  99.   { case C_NOINIT :  cp->dval = 0.0 ; break ;
  100.  
  101.     case C_DOUBLE :  goto two ;
  102.     case C_STRNUM :  
  103.             free_STRING( string(cp) ) ;
  104.             break ;
  105.  
  106.     case C_MBSTRN :
  107.     case C_STRING :  
  108.             s = (STRING *) cp->ptr ;
  109.  
  110. #if FPE_TRAPS_ON  /* look for overflow error */
  111.             errno = 0 ;
  112.             cp->dval = strtod(s->str,(char **)0) ;
  113.             if ( errno && cp->dval != 0.0 ) /* ignore underflow */
  114.                 rt_error("overflow converting %s to double", s) ;
  115. #else
  116.             cp->dval = strtod(s->str,(char **)0) ;
  117. #endif
  118.             free_STRING(s) ;
  119.             break ;
  120.  
  121.     default :
  122.             bozo("cast on bad type") ;
  123.   }
  124.   cp->type = C_DOUBLE ;
  125.  
  126. two:   cp++ ;
  127.   switch( cp->type )
  128.   { case C_NOINIT :  cp->dval = 0.0 ; break ;
  129.  
  130.     case C_DOUBLE :  return ;
  131.     case C_STRNUM :  
  132.             free_STRING( string(cp) ) ;
  133.             break ;
  134.  
  135.     case C_MBSTRN :
  136.     case C_STRING :  
  137.             s = (STRING *) cp->ptr ;
  138.  
  139. #if FPE_TRAPS_ON  /* look for overflow error */
  140.             errno = 0 ;
  141.             cp->dval = strtod(s->str,(char **)0) ;
  142.             if ( errno && cp->dval != 0.0 ) /* ignore underflow */
  143.                 rt_error("overflow converting %s to double", s) ;
  144. #else
  145.             cp->dval = strtod(s->str,(char **)0) ;
  146. #endif
  147.             free_STRING(s) ;
  148.             break ;
  149.  
  150.     default :
  151.             bozo("cast on bad type") ;
  152.   }
  153.   cp->type = C_DOUBLE ;
  154. }
  155.  
  156. void cast1_to_s( cp )
  157.   register CELL *cp ;
  158.   switch( cp->type )
  159.   { case C_NOINIT :  
  160.         null_str.ref_cnt++ ;
  161.         cp->ptr = (PTR) &null_str ;
  162.         break ;
  163.  
  164.     case C_DOUBLE  :
  165.         (void) sprintf(temp_buff.string_buff ,
  166.             string(field+OFMT)->str, cp->dval) ;
  167.  
  168.         cp->ptr = (PTR) new_STRING(temp_buff.string_buff) ;
  169.         break ;
  170.  
  171.     case C_STRING :  return ;
  172.  
  173.     case C_MBSTRN :
  174.     case C_STRNUM :  break ;
  175.  
  176.     default :  bozo("bad type on cast") ;
  177.   }
  178.   cp->type = C_STRING ;
  179. }
  180.  
  181. void cast2_to_s( cp )
  182.   register CELL *cp ;
  183.  
  184.   switch( cp->type )
  185.   { case C_NOINIT : 
  186.         null_str.ref_cnt++ ;
  187.         cp->ptr = (PTR) &null_str ;
  188.         break ;
  189.  
  190.     case C_DOUBLE  :
  191.         (void) sprintf(temp_buff.string_buff,
  192.             string(field+OFMT)->str, cp->dval ) ;
  193.  
  194.         cp->ptr = (PTR) new_STRING(temp_buff.string_buff) ;
  195.         break ;
  196.  
  197.     case C_STRING :  goto two ;
  198.  
  199.     case C_MBSTRN :
  200.     case C_STRNUM :  break ;
  201.  
  202.     default :  bozo("bad type on cast") ;
  203.   }
  204.   cp->type = C_STRING ;
  205.  
  206. two:
  207.   cp++ ;
  208.  
  209.   switch( cp->type )
  210.   { case C_NOINIT :  
  211.         null_str.ref_cnt++ ; 
  212.         cp->ptr = (PTR) &null_str ;
  213.         break ;
  214.  
  215.     case C_DOUBLE  :
  216.         (void) sprintf(temp_buff.string_buff,
  217.             string(field+OFMT)->str, cp->dval) ;
  218.  
  219.         cp->ptr = (PTR) new_STRING(temp_buff.string_buff) ;
  220.         break ;
  221.  
  222.     case C_STRING :  return ;
  223.  
  224.     case C_MBSTRN :
  225.     case C_STRNUM :  break ;
  226.  
  227.     default :  bozo("bad type on cast") ;
  228.   }
  229.   cp->type = C_STRING ;
  230. }
  231.  
  232. void  cast_to_RE( cp )
  233.   register CELL *cp ;
  234. { register PTR p ;
  235.  
  236.   if ( cp->type < C_STRING )  cast1_to_s(cp) ;
  237.  
  238.   p = re_compile( string(cp) ) ;
  239.   free_STRING( string(cp) ) ;
  240.   cp->type = C_RE ;
  241.   cp->ptr = p ;
  242.  
  243. }
  244.  
  245. void  cast_for_split(cp)
  246.   register CELL *cp ;
  247. {
  248.   static char meta[] = "^$.*+?|[]()" ;
  249.   static char xbuff[] = "\\X" ;
  250.   int c ;
  251.   unsigned len ;
  252.     
  253.   if ( cp->type < C_STRING )  cast1_to_s(cp) ;
  254.  
  255.   if ( (len = string(cp)->len) == 1 )
  256.   {
  257.         if ( (c = string(cp)->str[0]) == ' ' )
  258.         { free_STRING(string(cp)) ;
  259.           cp->type = C_SPACE ; 
  260.           return ; 
  261.         }
  262.         else
  263.         if ( strchr(meta, c) )
  264.         { xbuff[1] = c ;
  265.           free_STRING(string(cp)) ;
  266.           cp->ptr = (PTR) new_STRING(xbuff) ;
  267.         }
  268.   }
  269.   else
  270.   if ( len == 0 ) 
  271.   { free_STRING(string(cp)) ;
  272.     cp->type = C_SNULL ; 
  273.     return ; 
  274.   }
  275.  
  276.   cast_to_RE(cp) ;
  277. }
  278.  
  279. /* input: cp-> a CELL of type C_MBSTRN (maybe strnum)
  280.    test it -- casting it to the appropriate type
  281.    which is C_STRING or C_STRNUM
  282. */
  283.  
  284. void check_strnum( cp )
  285.   CELL *cp ;
  286. { char *test ;
  287.   register unsigned char *s , *q ;
  288.  
  289.   cp->type = C_STRING ; /* assume not C_STRNUM */
  290.   s = (unsigned char *) string(cp)->str ;
  291.   q = s + string(cp)->len ;
  292.   while ( scan_code[*s] == SC_SPACE )  s++ ;
  293.   if ( s == q )  return ;
  294.  
  295.   while ( scan_code[ q[-1] ] == SC_SPACE )  q-- ;
  296.   if ( scan_code[ q[-1] ] != SC_DIGIT &&
  297.        q[-1] != '.' )   return ;
  298.  
  299.   switch ( scan_code[*s] )
  300.   {
  301.     case SC_DIGIT :
  302.     case SC_PLUS  :
  303.     case SC_MINUS :
  304.     case SC_DOT   :
  305.  
  306. #if FPE_TRAPS_ON
  307.              errno = 0 ;
  308.              cp->dval  = strtod((char *)s, &test) ;
  309.              if ( errno && cp->dval != 0.0 )
  310.                 rt_error(
  311.                 "overflow converting %s to double" , s) ;
  312. #else
  313.              cp->dval = strtod((char *)s, &test) ;
  314. #endif
  315.  
  316.              if ((char *) q == test )  cp->type = C_STRNUM ;
  317.   }
  318. }
  319.  
  320. /* cast a CELL to a replacement cell */
  321.  
  322. void cast_to_REPL( cp )
  323.   register CELL *cp ;
  324. { register STRING *sval ;
  325.  
  326.   if ( cp->type < C_STRING )  cast1_to_s(cp) ;
  327.   sval = (STRING *) cp->ptr ;
  328.  
  329.   (void) cellcpy(cp, repl_compile(sval)) ;
  330.   free_STRING(sval) ;
  331. }
  332.  
  333.  
  334. #if   HAVE_STRTOD==0
  335.  
  336. static char d_str[] =
  337. "^[ \t]*[-+]?([0-9]+\\.?|\\.[0-9])[0-9]*([eE][-+]?[0-9]+)?" ;
  338.  
  339. static PTR d_ptr ;
  340.  
  341. void strtod_init()
  342. { STRING *sval = new_STRING(d_str) ;
  343.  
  344.   d_ptr = re_compile(sval) ;
  345.   free_STRING(sval) ;
  346. }
  347.  
  348. double strtod( s, endptr)
  349.   char *s , **endptr ;
  350. { double atof() ;
  351.  
  352.   if ( endptr )
  353.   { unsigned len ;
  354.  
  355.     (void) REmatch(s, d_ptr, &len) ;
  356.     *endptr = s + len ;
  357.   }
  358.   return  atof(s) ;
  359. }
  360. #endif  /* HAVE_STRTOD==0 */
  361.  
  362. #if   HAVE_FMOD==0
  363.  
  364. #if SW_FP_CHECK   /* this is V7 and XNX23A specific */
  365.  
  366. double  fmod(x, y)
  367.   double x, y ;
  368. { double modf() ;
  369.   double dtmp, ipart ;
  370.  
  371.   clrerr();
  372.   dtmp = x / y;
  373.   fpcheck();
  374.   return modf(dtmp, &ipart) * y ;
  375. }
  376.  
  377. #else
  378.  
  379. double  fmod(x, y)
  380.   double x, y ;
  381. { double modf() ;
  382.   double ipart ;
  383.  
  384.   return modf(x/y, &ipart) * y ;
  385. }
  386.  
  387. #endif
  388. #endif  
  389.  
  390.  
  391.  
  392.